<template>
  <div v-bind="$attrs"
       class="clearfix">
    <Upload :action="api"
            :accept="getStringAccept"
            :before-upload="beforeUpload"
            :list-type="listType"
            v-model:file-list="fileList"
            @change="uploadChange"
            @preview="handlePreview">
      <div v-if="fileList.length < maxNumber">
        <span class="icon">+</span>
        <div class="ant-upload-text">点击上传</div>
      </div>
    </Upload>
    <Modal v-model:visible="previewVisible"
           :footer="null"
           @cancel="handleCancel">
      <img alt="example"
           style="width: 100%"
           :src="previewImage" />
    </Modal>
  </div>
</template>

<script lang="ts">
import { Upload, Modal } from 'ant-design-vue';
import { defineComponent, ref, toRefs, unref, computed, watch } from 'vue';
import { useUploadType } from './useUpload';
import { FileItem } from './types';
import { basicProps } from './props';
import { useMessage } from '/@/hooks/web/useMessage';
import { Icon } from '/@/components/Icon';
function getBase64(file: File) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = (error) => reject(error);
  });
}

export default defineComponent({
  name: 'UploadFile',
  props: {
    ...basicProps,
  },
  components: {
    Upload,
    Modal,
    Icon,
  },
  emits: ['change'],
  setup(props, { emit }) {
    const previewVisible = ref<boolean>(false);
    const previewImage = ref<string | undefined>('');
    const fileList = ref<FileItem[]>([]);
    const imageList = ref<string[]>([]);
    const { list, accept, maxNumber, maxSize, api, listType, responseType } = toRefs(props);
    const { getAccept, getStringAccept } = useUploadType({
      acceptRef: accept,
      maxNumberRef: maxNumber,
      maxSizeRef: maxSize,
    });
    const key = ref<Number>(1);
    // fileList.value = list;
    console.log(fileList.value, list.value);
    const { createMessage } = useMessage();
    const handleCancel = () => {
      previewVisible.value = false;
    };
    const handlePreview = async (file: FileItem) => {
      if (!file.url && !file.preview) {
        file.preview = (await getBase64(file.originFileObj)) as string;
      }
      previewImage.value = file.url || file.preview;
      previewVisible.value = true;
    };
    const fileValues = computed(() => {
      return list.value;
    });
    watch(
      () => fileList.value,
      (visible, _) => {
        const file: any = visible[visible.length - 1];
        console.log(visible, file.status, _);
        if (file.status == 'done') {
          if (file.response.code == 200) {
            createMessage.success('上传成功！');
            const urlArr: string[] = [];
            if (unref(responseType) == 'arr') {
              fileList.map((item: any) => {
                urlArr.push(item.response.data[0]);
              });
            } else {
              fileList.map((item: any) => {
                urlArr.push(item.response.msg);
              });
            }
            fileList.value = [];
            imageList.value = urlArr;
            console.log(imageList.value);
            emit('change', urlArr);
            key.value = Math.random();
            console.log(key.value);
          } else {
            createMessage.success('上传失败！');
          }
        }
      }
    );
    // 上传前校验
    function beforeUpload(file: File) {
      // const { size, name } = file;
      const { maxSize } = props;
      const accept = unref(getAccept);
      // 设置最大值，则判断
      if (maxSize && file.size / 1024 / 1024 >= maxSize) {
        createMessage.error('文件过大');
        return false;
      }
      // 设置类型,则判断
      if (accept.length > 0 && !checkFileType(file, accept)) {
        createMessage.error!('请上传正确类型：', accept.join(','));
        return false;
      }
    }
    function checkFileType(file: File, accepts: string[]) {
      const newTypes = accepts.join('|');
      // const reg = /\.(jpg|jpeg|png|gif|txt|doc|docx|xls|xlsx|xml)$/i;
      const reg = new RegExp('\\.(' + newTypes + ')$', 'i');
      return reg.test(file.name);
    }
    function uploadChange(res: any) {
      const { file, fileList } = res;
      if (file.status == 'done') {
        if (file.response.code == 200) {
          createMessage.success('上传成功！');
          const urlArr: string[] = [];
          if (unref(responseType) == 'arr') {
            fileList.map((item: any) => {
              urlArr.push(item.response.data[0]);
            });
          } else {
            fileList.map((item: any) => {
              urlArr.push(item.response.msg);
            });
          }
          fileList.value = [];
          imageList.value = urlArr;
          console.log(imageList.value);
          emit('change', urlArr);
          key.value = Math.random();
          console.log(key.value);
        } else {
          createMessage.success('上传失败！');
        }
      }
    }
    return {
      fileList,
      fileValues,
      handleCancel,
      handlePreview,
      getStringAccept,
      beforeUpload,
      api,
      previewVisible,
      previewImage,
      uploadChange,
      listType,
      imageList,
      key,
    };
  },
});
</script>

<style scoped>
.clearfix {
  display: flex;
  justify-items: flex-start;
}
.img-box {
  width: 104px;
  height: 104px;
  padding: 8px;
  margin: 0 8px 8px 0;
  border: 1px solid #d9d9d9;
  border-radius: 2px;
}
.img-box img {
  width: 100%;
  height: 100%;
}
:deep(.ant-upload) {
  position: relative;
}
.ant-upload .icon {
  position: absolute;
  top: 50%;
  left: 50%;
  font-size: 26px;
  font-weight: 300;
  color: #666;
  transform: translate(-50%, -100%);
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
</style>
